<template>
	<view class="dynamic-form-wrapper">
		<uni-forms ref="dynamicForm" :modelValue="dynamicFormData" :label-position="labelPosition"
			:label-width="labelWidth" :label-align='labelAlign'>
			<uni-row gutter=20>
				<uni-col v-for="(item, index) in dynamicFormData.items" :span="item.singleRow == 1 ? 24 : 12"
					:key="index">
					<uni-forms-item :label="item.label" :rules="item.rules" :key="item.id"
						:name="['items',index,'value']">
						<template v-if="item.type == 'SELECT'">
							<uni-data-select v-model="dynamicFormData.items[index].value" :localdata="item.options"
								:disabled="item.disabled" :placeholder="item.placeHolder"
								@change="handleSelectChange($event, item)"></uni-data-select>
						</template>
						<template v-else-if="item.type == 'RADIO'">
							<uni-data-checkbox v-model="dynamicFormData.items[index].value" :localdata="item.options"
								:multiple="false" :disabled="item.disabled"></uni-data-checkbox>
						</template>
						<template v-else-if="item.type == 'CHECKBOX'">
							<uni-data-checkbox v-model="dynamicFormData.items[index].value" :localdata="item.options"
								multiple :disabled="item.disabled" :min="item.checkBoxRule.min"
								:max="item.checkBoxRule.max"></uni-data-checkbox>
						</template>
						<template v-else-if="item.type == 'INPUT'">
							<uni-easyinput v-model="dynamicFormData.items[index].value" :placeholder="item.placeHolder"
								:disabled="item.disabled" :readonly="item.readonly" />
						</template>
						<template v-else>
							<uni-easyinput v-model="dynamicFormData.items[index].value" type="textarea"
								:placeholder="item.placeHolder" :disabled="item.disabled" :readonly="item.readonly" />
						</template>
					</uni-forms-item>
				</uni-col>
			</uni-row>
			<view class="dynamic-form-btns">
				<button :class="submitBtnClass" @click="submitForm">{{ submitBtnName }}</button>
				<template>
					<slot></slot>
				</template>
			</view>
		</uni-forms>
	</view>
</template>

<script>
	export default {
		name: 'auto-create-form',
		props: {
			formItems: {
				type: Array,
				required: true
			},
			submitBtnName: {
				type: String,
				default: '确定'
			},
			labelWidth: {
				type: String,
				default: '75px'
			},
			labelPosition: {
				type: String,
				default: 'left'
			},
			labelAlign:{
				type: String,
				default: 'left'
			},
			submitBtnClass: {
				type: String,
				default: ''
			}
		},
		data() {
			return {
				dynamicFormData: {
					items: []
				},
				sourceForm: {
					items: []
				}
			}
		},

		mounted() {
			const fieldMap = new Map()
			fieldMap.set(1, 'SELECT')
			fieldMap.set(2, 'RADIO')
			fieldMap.set(3, 'CHECKBOX')
			fieldMap.set(4, 'INPUT')
			fieldMap.set(5, 'TEXTAREA')

			let formSortedItems = JSON.parse(JSON.stringify(this.formItems))
			//根据sortNum排序
			formSortedItems.sort((a, b) => {
				if (a.sortNum < b.sortNum) return -1
				if (a.sortNum > b.sortNum) return 1
				return 0
			})

			let asyncReqPromises = [],
				itemIndexArr = []
			formSortedItems.forEach((fitem, index) => {
				let item = {
					value: fitem.defaultValue,
					id: fitem.fieldConfigId,
					fieldName: fitem.fieldName,
					label: fitem.fieldTitle,
					placeHolder: fitem.placeHolder,
					readonly: fitem.editFlag === 0,
					disabled: fitem.usingFlag == 0,
					sortNum: fitem.sortNum,
					singleRow: fitem.singleRow,
					dataUrl: fitem.dataUrl,
					linkAge: fitem.linkAge,
					linkageField: fitem.linkageField,
					type: fieldMap.get(fitem.fieldShowForm),
					rules: [{
						required: fitem.mustInput === 1,
						errorMessage: fitem.placeHolder
					}]
				}
				//异步获取下拉框选项列表
				if (item.type == 'SELECT' && fitem.controlDataFlag === 1) {
					let asyncReq = this.getRemoteData(
						fitem.dataUrl,
						fitem.linkageField !== '' ? {
							id: '-1'
						} : {
							id: '430000'
						}
					)
					asyncReqPromises.push(asyncReq)
					itemIndexArr.push(index)
					item.options = []
				}
				//选项列表由controlData转化
				if (
					(item.type == 'SELECT' ||
						item.type == 'RADIO' ||
						item.type == 'CHECKBOX') &&
					fitem.controlDataFlag === 0 &&
					fitem.controlData != ''
				) {
					let controlData = JSON.parse(fitem.controlData),
						optionsData = []
					controlData.forEach(item => {
						optionsData.push({
							value: item.id,
							text: item.value
						})
					})
					item.options = optionsData
				}
				if (item.type == 'CHECKBOX') {
					const checkBoxRule = JSON.parse(fitem.checkBoxRule)
					item.checkBoxRule = {
						min: parseInt(checkBoxRule.minNum),
						max: parseInt(checkBoxRule.maxNum)
					}
					item.value = []
				}
				if (fitem.regex != '') {
					///^[\\u4E00-\\u9FA5A-Za-z0-9（） ·《》]+$/
					item.rules.push({
						pattern: fitem.regex.substring(1, fitem.regex.length - 1),
						errorMessage: fitem.showMsg
					})
				}
				this.dynamicFormData.items.push(item)
				this.sourceForm.items.push(JSON.parse(JSON.stringify(item)))
			})
			if (asyncReqPromises.length > 0) {
				Promise.all(asyncReqPromises).then((results) => {
					results.forEach((item, index) => {
						let data = item.data,
							optionsData = []
						data.forEach(item => {
							optionsData.push({
								value: item.id,
								text: item.value
							})
						})
						this.dynamicFormData.items[itemIndexArr[index]].options = optionsData
						this.sourceForm.items[itemIndexArr[index]].options = optionsData
					})
				})
			}
		},
		methods: {
			getRemoteData(dataUrl, params) {
				const match = dataUrl.match(/^(https?:\/\/)?(?:[^@\n]+@)?([^:/?#]+)(?::(\d+))?/);
				const orignalDomain =  match[0];
				const url = dataUrl.replace(orignalDomain,import.meta.env.VITE_APP_BASE_URL);
				return new Promise((res, rej) => {
					uni.request({
						url: url + params.id,
						method: 'GET',
						success: (result) => {
							res(result.data)
						},
						fail: (err) => {
							rej(err)
						}
					})
				})
			},
			//二级联动数据获取
			handleSelectChange(value, item) {
				if (item.linkAge === 1) {
					const fieldName = item.linkageField

					const linkFieldItem = this.dynamicFormData.items.find(
						(it) => it.fieldName == fieldName
					)
					this.getRemoteData(item.dataUrl, {
						id: value
					}).then((res) => {
						let data = res.data,
							optionsData = []
						data.forEach(item => {
							optionsData.push({
								value: item.id,
								text: item.value
							})
						})
						linkFieldItem.options = optionsData
						linkFieldItem.value = data.length > 0 ? data[0].id : ''
					})
				}
			},
			//提交表单
			submitForm() {
				this.$refs['dynamicForm'].validate().then(res => {
					let data = new Map(),
						formData = res.items
					this.dynamicFormData.items.forEach((item, index) => {
						data.set(item.fieldName, formData[index].value)
						//多选框的值用#连接
						if (item.type == 'CHECKBOX')
							data.set(item.fieldName, formData[index].value.join('#'))
					})

					this.$emit('submit', Object.fromEntries(data))

				}).catch(err => {
					console.error('表单错误信息：', err);
				})
			},
			//重置：对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
			resetFields() {
				this.$refs['dynamicForm'].clearValidate()
				let sourceItems = this.sourceForm.items
				this.dynamicFormData.items.forEach((item, index) => {
					if (item.value != sourceItems[index].value) {
						item.value = sourceItems[index].value
						item.valueName = sourceItems[index].valueName
					}
				})
			}
		}
	}
</script>

<style>

</style>